﻿using System;
using System.IO;
using System.Net;
using System.Collections.Generic;

namespace ExcelConfig.StoreAPI
{
    using SanlieHash;
    using SanlieHash.Fast;
    using SanlieHash.GuoMi;
    using ExcelConfig.StoreAPI.Dto;
    using wuo;
    using ExcelConfig.StoreAPI.ec_eng;
    using ExcelConfig.StoreAPI._req;
    using ExcelConfig.StoreAPI.helpers;
    using ExcelConfig.Config;

    public class ConfigStoreAPI
    {
        internal static IEC ec = new ec_202508();
        public static string ServeUri { get { return AppConfig.Text("配置中心地址"); } }
        public static string ApiPath { get { return $"{ServeUri}/store/config"; } }
        internal static string NewParam(string method, Dictionary<string, string> obj)
        {
            var input = new ConfigStoreInput();
            input.Method = method;
            input.Params = obj;
            var msg = WuoConvert.SerializeObject(input);
            return ec.Encrypt(msg);
        }
        internal static bool is_success(HttpStatusCode code)
        {
            return code == HttpStatusCode.OK || code == HttpStatusCode.Created || code == HttpStatusCode.NoContent;
        }
        public static void PleaseInputPassword()
        {
            if (string.IsNullOrEmpty(AppConfig.Text("验证密码")))
            {
                Console.Write("press you config password: ");
                var pwd = Console.ReadLine();
                if (pwd != null && (pwd = pwd.Trim()) != string.Empty) AppConfig.WriteText("验证密码", pwd);
            }
        }
        /// <summary>
        /// 新建一个配置
        /// </summary>
        public static bool NewConfig(string zone, string name)
        {
            var content = NewParam("new", new Dictionary<string, string>{ ["zone"] = zone, ["name"] = name });
            var status = http_client.JustPost(ApiPath, content);
            return is_success(status);
        }
        public static IExcelConfig GetStreamConfig(string zone, string name)
        {
            var stream = Download(zone, name);
            return new AppConfigStreamFile(stream);
        }
        /// <summary>
        /// 写一个配置项
        /// </summary>
        public static bool Write(string zone, string name, string field, string value)
        {
            var v_pwd = Guid.NewGuid().ToString("N");
            value = FastGuoMi.EncryptSM4(value, v_pwd + AppConfig.Text("验证密码"));
            var content = NewParam("value", new Dictionary<string, string> { ["zone"] = zone, ["name"] = name, ["key"] = field, ["value"] = value, ["method"] = "set", ["password"] = v_pwd });
            var status = http_client.JustPost(ApiPath, content);
            return is_success(status);
        }
        /// <summary>
        /// 读一个配置项
        /// </summary>
        public static string Read(string zone, string name, string field)
        {
            var v_pwd = Guid.NewGuid().ToString("N");
            var content = NewParam("value", new Dictionary<string, string> { ["zone"] = zone, ["name"] = name, ["key"] = field, ["method"] = "get", ["password"] = v_pwd});
            var outtext = http_client.Post(ApiPath, content);
            var rlt = WuoConvert.DeserializeObject<ConfigStoreOutput>(outtext);
            if (rlt != null && rlt.Success)
            {
                var v = string.Empty;
                if (rlt.Params.ContainsKey("value"))
                {
                    v = rlt.Params["value"].ToString() ?? string.Empty;
                    if (!string.IsNullOrEmpty(v)) v = FastGuoMi.DecryptSM4(v, v_pwd + AppConfig.Text("验证密码"));
                }
                return v;
            }

            return string.Empty;
        }
        public static string[] ListZoneName()
        {
            return ListConfigName(string.Empty);
        }
        public static string[] ListConfigName(string zone)
        {
            var v_pwd = Guid.NewGuid().ToString("N");
            var content = NewParam("ls", new Dictionary<string, string> { ["zone"] = zone, ["password"] = v_pwd });
            var outtext = http_client.Post(ApiPath, content);
            var rlt = WuoConvert.DeserializeObject<ConfigStoreOutput>(outtext);
            if (rlt != null && rlt.Success)
            {
                var v = string.Empty;
                if (rlt.Params.ContainsKey("value"))
                {
                    v = rlt.Params["value"].ToString() ?? string.Empty;
                    if (!string.IsNullOrEmpty(v)) v = FastGuoMi.DecryptSM4(v, v_pwd + AppConfig.Text("验证密码"));
                }
                return v.Split(';');
            }

            return new string[0];
        }
        /// <summary>
        /// 下载一个配置到流
        /// </summary>
        public static Stream? Download(string zone, string name)
        {
            var content = NewParam("get", new Dictionary<string, string> { ["zone"] = zone, ["name"] = name });
            using var responseStream = http_client.PostDownload(ApiPath, content, out var filename);

            if (responseStream == null) return null;
            Stream stream;
            {
                sm4.New();
                sm4.SetKey(FastHash.GetMD5Bytes(AppConfig.Text("验证密码")));
                var buf = new byte[responseStream.Length];
                var x = responseStream.Read(buf, 0, buf.Length);
                stream = new MemoryStream(sm4.Decrypt(buf));
            }
            return stream;
        }
        internal static SM4 sm4 = new SM4();
        /// <summary>
        /// 下载一个配置到文件
        /// </summary>
        public static bool DownloadToFile(string zone, string name, string filepath)
        {
            var content = NewParam("get", new Dictionary<string, string> { ["zone"] = zone, ["name"] = name });
            using var responseStream = http_client.PostDownload(ApiPath, content, out var filename);
            if (responseStream == null) return false;
            var path = filepath;
            if (string.IsNullOrEmpty(path)) path = $"./{zone}/{filename}";
            MemoryStream mem;
            {
                sm4.New();
                sm4.SetKey(FastHash.GetMD5Bytes(AppConfig.Text("验证密码")));
                var buf = new byte[responseStream.Length];
                var x = responseStream.Read(buf, 0, buf.Length);
                mem = new MemoryStream(sm4.Decrypt(buf));
            }
            using (mem)
            {
                using var fileStream = File.Create(path);
                helper.ReadAllToMemory(mem, fileStream);
            }
            return true;
        }
        /// <summary>
        /// 上传一个配置
        /// </summary>
        public static bool Upload(string zone, string name, string path, bool record = false)
        {
            var content = NewParam(record ? "setset" : "set", new Dictionary<string, string> { ["zone"] = zone, ["name"] = name });
            var multi = new multi_content();
            path = path.Trim('"');
            using var fileStream = File.OpenRead(path);
            MemoryStream mem;
            {
                sm4.New();
                sm4.SetKey(FastHash.GetMD5Bytes(AppConfig.Text("验证密码")));
                var buf = new byte[fileStream.Length];
                var x = fileStream.Read(buf, 0, buf.Length);
                mem = new MemoryStream(sm4.Encrypt(buf));
            }
            using (mem)
            {
                multi.AddContent("param", content);
                multi.AddFileContent("config.xlsx", mem);
                var status = http_client.JustPostUpload(ApiPath, multi);
                return is_success(status);
            }
        }
    }
}
